package com.jzo2o.foundations.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.api.foundations.dto.response.ConfigRegionInnerResDTO;
import com.jzo2o.api.foundations.dto.response.ServeAggregationResDTO;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.foundations.constants.RedisConstants;
import com.jzo2o.foundations.enums.FoundationStatusEnum;
import com.jzo2o.foundations.mapper.ConfigRegionMapper;
import com.jzo2o.foundations.mapper.RegionMapper;
import com.jzo2o.foundations.mapper.ServeItemMapper;
import com.jzo2o.foundations.mapper.ServeMapper;
import com.jzo2o.foundations.model.domain.*;
import com.jzo2o.foundations.model.dto.request.ConfigRegionSetReqDTO;
import com.jzo2o.foundations.model.dto.request.ServePageQueryReqDTO;
import com.jzo2o.foundations.model.dto.request.ServeUpsertReqDTO;
import com.jzo2o.foundations.model.dto.response.ConfigRegionResDTO;
import com.jzo2o.foundations.model.dto.response.ServeResDTO;
import com.jzo2o.foundations.service.IConfigRegionService;
import com.jzo2o.foundations.service.IServeService;
import com.jzo2o.mysql.utils.PageHelperUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import com.jzo2o.foundations.model.domain.Serve;

/**
 * <p>
 * 区域业务配置 服务实现类
 * </p>
 *
 * @author itcast
 * @since 2023-08-21
 */
@Service
public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements IServeService {

    @Resource
    private ServeItemMapper serveItemMapper;
    @Resource
    private RegionMapper regionMapper;

    @Override
    public PageResult<ServeResDTO> pageServeRegion(ServePageQueryReqDTO servePageQueryReqDTO) {
        return PageHelperUtils.selectPage(servePageQueryReqDTO,
                ()->baseMapper.pageServeRegion(servePageQueryReqDTO.getRegionId()));
    }

    @Override
    @Transactional
    public void deleteServeRegionByServeId(long id) {
        Serve serve = baseMapper.selectById(id);
        if (Objects.isNull(serve)) {
            throw new ForbiddenOperationException("服务项不存在");
        }
        //todo 禁用的时候不能删除，是因为可能已经产生了业务数据(还是再考虑一下吧)
        if (!(serve.getSaleStatus()== FoundationStatusEnum.INIT.getStatus())) {
            throw new ForbiddenOperationException("草稿状态方可删除！");
        }

        baseMapper.deleteById(id);
    }

    @Override
    public void updateSaleStatusByServeId(long id) {
        Serve serve = baseMapper.selectByServerId(id);
        if (serve.getSaleStatus()!= FoundationStatusEnum.ENABLE.getStatus()) {
            throw new ForbiddenOperationException("上架的时候才可以下架");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("itemId", id);
        map.put("status", FoundationStatusEnum.DISABLE.getStatus());
        baseMapper.updateSaleStatusByServeId(map);
    }

    @Override
    public void setOnHotByServeId(long id) {
        LambdaUpdateWrapper<Serve> lambdaUpdateWrapper
                = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.eq(Serve::getId, id);
                lambdaUpdateWrapper.set(Serve::getIsHot, 1);
                lambdaUpdateWrapper.set(Serve::getHotTimeStamp, System.currentTimeMillis());
                baseMapper.update(null, lambdaUpdateWrapper);
    }

    @Override
    public void setOffHotByServeId(long id) {
        LambdaUpdateWrapper<Serve> lambdaUpdateWrapper
                = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(Serve::getId, id);
        lambdaUpdateWrapper.set(Serve::getIsHot, 0);
        lambdaUpdateWrapper.set(Serve::getHotTimeStamp, System.currentTimeMillis());
        baseMapper.update(null, lambdaUpdateWrapper);
    }

    @Override
    public int queryServeCountByRegionIdAndSaleStatus(Long id, int status) {
        LambdaQueryWrapper<Serve> serveLambdaQueryWrapper =
                new LambdaQueryWrapper<>();
        serveLambdaQueryWrapper.eq(Serve::getRegionId,id);
//        注意这里调用的要写明status
        serveLambdaQueryWrapper.eq(ObjectUtil.isNotEmpty(status),
                Serve::getSaleStatus,status);
        return baseMapper.selectCount(serveLambdaQueryWrapper);
    }

    @Override
    public int queryServeCountByServeItemIdAndSaleStatus(Long id, int status) {
        LambdaQueryWrapper<Serve> serveLamdaQueryWrapper =
                new LambdaQueryWrapper<Serve>();
        serveLamdaQueryWrapper.eq(Serve::getServeItemId,id);
        //        注意这里调用的要写明status
        serveLamdaQueryWrapper.eq(ObjectUtil.isNotEmpty(status),Serve::getSaleStatus,status);
        return baseMapper.selectCount(serveLamdaQueryWrapper);
    }

    @Override
    @Transactional
    public void add(List<ServeUpsertReqDTO> serveUpsertReqDTOS) {
        for (ServeUpsertReqDTO serveUpsertReqDTO : serveUpsertReqDTOS) {

            ServeItem serveItem = serveItemMapper.selectById(serveUpsertReqDTO.getServeItemId());

            if (ObjectUtil.isNull(serveItem)||!(serveItem.getActiveStatus()==
                    FoundationStatusEnum.ENABLE.getStatus())) {
                throw new ForbiddenOperationException("该服务未启用无法添加到区域下使用");
            }

            LambdaQueryWrapper<Serve> serveLambdaQueryWrapper =
                    new LambdaQueryWrapper<>();
            LambdaQueryWrapper<Serve> query = serveLambdaQueryWrapper
                    .eq(Serve::getServeItemId, serveUpsertReqDTO.getServeItemId())
                    .eq(Serve::getRegionId, serveUpsertReqDTO.getRegionId());

            Integer count = baseMapper.selectCount(query);
            if (count>0) {
                throw new ForbiddenOperationException("该服务已添加到该区域下");
            }
            Serve serve = BeanUtils.toBean(serveUpsertReqDTO, Serve.class);
//            设置为服务项的的价格
            serve.setPrice(serveItem.getReferencePrice());
            Region region = regionMapper.selectById(serveUpsertReqDTO.getRegionId());
            serve.setCityCode(region.getCityCode());
            baseMapper.insert(serve);
        }
    }

    @Override
    public Serve updateRegionPrice(Long id, BigDecimal price) {
        LambdaUpdateWrapper<Serve> query =
                new LambdaUpdateWrapper<>();
        LambdaUpdateWrapper<Serve> query2 =
                query.eq(Serve::getId, id)
                        .set(Serve::getPrice, price);
        baseMapper.update(null,query2);
        //这里没有在controller中返回数据，因为前端代码是通过其他接口获取数据。
        return baseMapper.selectById(id);
    }

    @Override
    @Transactional
    public Serve onSale(Long id) {
        Serve serve = baseMapper.selectById(id);
        if (ObjectUtil.isNull(serve)) {
            throw new ForbiddenOperationException("区域服务不存在");
        }

        if (serve.getSaleStatus()!= FoundationStatusEnum.INIT.getStatus()||
                serve.getSaleStatus()!=FoundationStatusEnum.DISABLE.getStatus()) {
            throw new ForbiddenOperationException("服务只有草稿或者下架才能上架");
        }

        Long serveItemId = serve.getServeItemId();
        ServeItem serveItem = serveItemMapper.selectById(serveItemId);

        if (ObjectUtil.isNull(serveItem)) {
            throw new ForbiddenOperationException("所属服务项不存在");
        }


        LambdaUpdateWrapper<Serve> serveLambdaUpdateWrapper =
                new LambdaUpdateWrapper<>();

        LambdaUpdateWrapper<Serve> query =
                serveLambdaUpdateWrapper.eq(Serve::getId, id)
                .set(Serve::getSaleStatus,
                FoundationStatusEnum.ENABLE.getStatus());
        int update = baseMapper.update(null, query);
        if (update<=0) {
            throw new ForbiddenOperationException("服务上架失败");
        }

        Serve serve2 = baseMapper.selectById(id);
        return serve2;


    }

    @Override
    @Transactional
    public void deleteServe(Long id) {
        Serve serve = baseMapper.selectById(id);
        if (ObjectUtil.isNull(serve)) {
            throw new ForbiddenOperationException("区域服务不存在");
        }

        if (serve.getSaleStatus()!= FoundationStatusEnum.INIT.getStatus()) {
            throw new ForbiddenOperationException("只有草稿状态的服务才能删除");
        }
      baseMapper.deleteById(id);


    }

    @Override
    @Transactional
    public void offSale(Long id) {
        Serve serve = baseMapper.selectById(id);
        if (ObjectUtil.isNull(serve)) {
            throw new ForbiddenOperationException("区域服务不存在");
        }
        Integer saleStatus = serve.getSaleStatus();
        if (!(saleStatus== FoundationStatusEnum.ENABLE.getStatus()||
                saleStatus==FoundationStatusEnum.INIT.getStatus())) {
            throw new ForbiddenOperationException("只有上架或者草稿的服务才能下架");
        }
        ServeItem serveItem = serveItemMapper.selectById(serve.getServeItemId());
        if (ObjectUtil.isNull(serveItem)) {
            throw new ForbiddenOperationException("所属服务项不存在");
        }
        if (serveItem.getActiveStatus()!= FoundationStatusEnum.ENABLE.getStatus()) {
            throw new ForbiddenOperationException("所属服务项未启用");
        }
        LambdaUpdateWrapper<Serve> objectLambdaUpdateWrapper =
                new LambdaUpdateWrapper<>();
        LambdaUpdateWrapper<Serve> set = objectLambdaUpdateWrapper
                .eq(Serve::getId, id)
                .set(Serve::getSaleStatus, FoundationStatusEnum.DISABLE.getStatus());
        baseMapper.update(null, set);
    }

    @Override
    @Cacheable(value = RedisConstants.CacheName.SERVE, key = "#id",
            cacheManager = RedisConstants.CacheManager.ONE_DAY)
    public Serve selectByIdCache(Long id) {
       return baseMapper.selectById(id);
    }

    @Override
    public ServeAggregationResDTO findServeDetailById(Long id) {

        return baseMapper.findServeDetailById(id);
    }
}
